package com.itstyle.seckill.topic.jichu;

/**
 * @Auther: liuwenxiang
 * @Date: 2020/3/12 17:44
 * @Description:
 * https://blog.csdn.net/qq_25269997/article/details/78168555
 */
public class TestShunxu {

    int a =1;

    static  int b =2;

    static {
        System.out.println("静态代码块"+b);
    }
    {
        System.out.println("非静态代码块"+a);
    }

    private TestShunxu(){
        System.out.println("构造方法");
    }


    static void aa(){
        b=3;
        System.out.println("静态方法");

    }

     void bb(){
        System.out.println("普通方法");

    }

    public static void main(String[] args) {
        System.out.println(TestShunxu.b);

        //System.out.println(new TestShunxu().a);
        //类加载的时候，就会执行静态资源，静态代码块--静态变量---静态方法
        //加载-链接(验证-准备-解析)-初始化-使用-卸载
        /**
         * 加载：将class字节码加载到内存--将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构.未分配空间
         * 验证：字节码符不符合jvm加载的规范
         * 准备：正式为"类变量"分配内存并设置类变量初始值的阶段(默认值，eg int类型默认值为0) final类型在准备阶段会设置初始值
         * 解析：jvm将常量池内的"符号引用"替换为"直接引用"的过程
         * 初始化：为变量赋值(只是静态//非静态的要实例化的时候才赋值)
         * 使用：使用对象
         * 卸载：垃圾回收
         *
         * ps:默认值与初始值不同概念
         *
         * 将产生初始化的情况：
         * 遇到new,getstatic,putstatic,invokestatic这失调字节码指令时，如果类没有进行过初始化，则需要先触发其初始化。
         *
         * 生成这4条指令的最常见的Java代码场景是：使用"new"关键字实例化对象的时候、"读取"或"设置"一个类的"静态字段"（被final修饰、已在编译器把结果放入常量池的静态字段除外）的时候，以及调用一个类的静态方法的时候。
         * 使用java.lang.reflect包的方法对类进行反射调用的时候，如果类没有进行过初始化，则需要先触发其初始化。
         * 当初始化一个类的时候，如果发现其父类还没有进行过初始化，则需要先触发其父类的初始化。
         * 当虚拟机启动时，用户需要指定一个要执行的主类（包含main()方法的那个类），虚拟机会先初始化这个主类。
         * 当使用jdk1.7动态语言支持时，如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getstatic,REF_putstatic,REF_invokeStatic的方法句柄，并且这个方法句柄所对应的类没有进行初始化，则需要先出触发其初始化。


           ps:通过子类引用父类的静态字段，不会导致子类初始化
         */

        /**
         * 类的初始化，是完成程序执行前的准备工作。在这个阶段，静态的（变量，代码块）会被执行。同时在会开辟一块存储空间用来存放静态的数据。初始化只在类加载的时候执行一次。
         * 类的实例化，是指创建一个对象的过程。这个过程中会在堆中开辟内存，将一些非静态的方法，变量存放在里面。在程序执行的过程中，可以创建多个对象，既多次实例化。每次实例化都会开辟一块新的内存。
         * ————————————————

         */

        //Class.forName("");加载，解释 ==执行类中的static块
        //classLoader 加载 ==不执行类中的static块，只有在newInstance才会去执行static块


        /**
         1、类内容（静态变量、静态初始化块） => 实例内容（变量、初始化块、构造器）
         2、父类的（静态变量、静态初始化块）=> 子类的（静态变量、静态初始化块）=> 父类的（变量、初始化块、构造器）=> 子类的（变量、初始化块、构造器）
         ps:初始化块可以对在它之后定义的变量赋值，但不能访问
         */



    }
}
